from ai import AI1Step
import time
import os


class Gomoku:
    def __init__(self):
        self.g_map = [[0 for y in range(15)] for x in range(15)]  # 当前的棋盘
        self.cur_step = 0  # 步数

    def move_1step(self, input_by_window=True, pos_x=None, pos_y=None):
        # 玩家落子
        while True:
            try:
                if not input_by_window:
                    pos_x = int(input('x: '))  # 接受玩家的输入人
                    pos_y = int(input('y: '))
                if 0 <= pos_x <= 14 and 0 <= pos_y <= 14:  # 判断这个格子能否落子
                    if self.g_map[pos_x][pos_y] == 0:
                        self.g_map[pos_x][pos_y] = 1
                        self.cur_step += 1
                        return
            except ValueError:
                continue

    def game_result(self):
        # 判断游戏结局。0为进行中，1为玩家胜，2为AI胜
        # 1. 判断是否横向连续五子
        for x in range(11):
            for y in range(15):
                if self.g_map[x][y] == 1 \
                        and self.g_map[x + 1][y] == 1 and self.g_map[x + 2][y] == 1 \
                        and self.g_map[x + 3][y] == 1 and self.g_map[x + 4][y] == 1:
                    return 1
                if self.g_map[x][y] == 2 \
                        and self.g_map[x + 1][y] == 2 and self.g_map[x + 2][y] == 2 \
                        and self.g_map[x + 3][y] == 2 and self.g_map[x + 4][y] == 2:
                    return 2

        # 2. 判断是否纵向连续五子
        for x in range(15):
            for y in range(11):
                if self.g_map[x][y] == 1 \
                        and self.g_map[x][y + 1] == 1 and self.g_map[x][y + 2] == 1 \
                        and self.g_map[x][y + 3] == 1 and self.g_map[x][y + 4] == 1:
                    return 1
                if self.g_map[x][y] == 2 \
                        and self.g_map[x][y + 1] == 2 and self.g_map[x][y + 2] == 2 \
                        and self.g_map[x][y + 3] == 2 and self.g_map[x][y + 4] == 2:
                    return 2
        # 3. 判断是否有左上-右下的连续五子
        for x in range(11):
            for y in range(11):
                if self.g_map[x][y] == 1 and self.g_map[x + 1][y + 1] == 1 and self.g_map[x + 2][y + 2] == 1 \
                        and self.g_map[x + 3][y + 3] == 1 and self.g_map[x + 4][y + 4] == 1:
                    return 1
                if self.g_map[x][y] == 2 and self.g_map[x + 1][y + 1] == 2 and self.g_map[x + 2][y + 2] == 2 \
                        and self.g_map[x + 3][y + 3] == 2 and self.g_map[x + 4][y + 4] == 2:
                    return 2
        # 4. 判断是否有右上-左下的连续五子
        for x in range(11):
            for y in range(11):
                if self.g_map[x + 4][y] == 1 and self.g_map[x + 3][y + 1] == 1 and self.g_map[x + 2][y + 2] == 1 \
                        and self.g_map[x + 1][y + 3] == 1 and self.g_map[x][y + 4] == 1:
                    return 1
                if self.g_map[x + 4][y] == 2 and self.g_map[x + 3][y + 1] == 2 and self.g_map[x + 2][y + 2] == 2 \
                        and self.g_map[x + 1][y + 3] == 2 and self.g_map[x][y + 4] == 2:
                    return 2
        # 5. 判断是否为平局
        for x in range(15):
            for y in range(15):
                if self.g_map[x][y] == 0:  # 棋盘中还有剩余的格子，不能判断为平局
                    return 0
        return 3

    def ai_play_1step(self):
        ai = AI1Step(self, self.cur_step, True)  # AI判断下一步执行什么操作
        st = time.time()
        ai.search(0, [set(), set()], self.max_search_steps)  # 最远看2回合之后
        ed = time.time()
        print('生成了%d个节点，用时%.4f，评价用时%.4f' % (len(ai.method_tree), ed - st, ai.t))
        if ai.next_node_dx_list[0] == -1:
            raise ValueError('ai.next_node_dx_list[0] == -1')
        ai_ope = ai.method_tree[ai.next_node_dx_list[0]].ope
        if self.g_map[ai_ope[0]][ai_ope[1]] != 0:
            raise ValueError('self.game_map[ai_ope[0]][ai_ope[1]] = %d' % self.g_map[ai_ope[0]][ai_ope[1]])
        self.g_map[ai_ope[0]][ai_ope[1]] = 2
        self.cur_step += 1

    def ai_move_1step(self):
        self.max_search_steps = 2
        self.ai_play_1step()
